﻿using ServerCommon.Config;
using ServerCommon.Log;
using ServerCommon.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LoginServer.Server
{
    public class LoginNet
    {
        public static readonly LoginNet Instance = new Lazy<LoginNet>(() => new LoginNet(), true).Value;
        private static LogHelper log = LogHelper.GetLogger(typeof(LoginNet));

        NetNodeManager _managerLogin;
        NetService _serviceLogin;

        NetNodeManager _managerGM;
        NetClient _clientGM;

        NetNodeManager _managerGateway;

        NetNodeManager _managerDatabase;
        NetClient _clientDatabase;

        public void Init()
        {
            _managerLogin = new NetNodeManager();
            _managerLogin.Init();

            _managerGM = new NetNodeManager();
            _managerGM.Init();

            _managerGateway = new NetNodeManager();
            _managerGateway.Init();

            _managerDatabase = new NetNodeManager();
            _managerDatabase.Init();

            var netConfig = ConfigManager.Instance.NetConfig["NetConfigure"];
            var loginNetConfig = netConfig["LoginNetConfig"];
            var serviceNetConfig = loginNetConfig["GameService"];
            int connectionCount = serviceNetConfig.Value<int>("MaxConnection");
            int bufferSize = serviceNetConfig.Value<int>("SAEABufferSize");

            var serverConfig = ConfigManager.Instance.ServerConfig;
            var loginConfig = serverConfig["LoginServer"];
            string ip = loginConfig.Value<string>("Ip");
            int port = loginConfig.Value<int>("Port");
            long localServerId = loginConfig.Value<long>("Id");

            _serviceLogin = new NetService();
            _serviceLogin.Config(_managerLogin, EnumNodeServiceType.Database, ip, port, connectionCount, bufferSize, localServerId);
            _serviceLogin.Start();
            _serviceLogin.ShowPrompt();

            var clientNetConfig = netConfig["ServerCustomConfig"];
            connectionCount = clientNetConfig.Value<int>("MaxConnection");
            bufferSize = clientNetConfig.Value<int>("SAEABufferSize");

            var gmConfig = serverConfig["GMServer"];
            ip = gmConfig.Value<string>("Ip");
            port = gmConfig.Value<int>("Port");
            long gmServerId = gmConfig.Value<long>("Id");
            _clientGM = new NetClient();
            _clientGM.Config(_managerGM, ip, port, connectionCount, bufferSize, gmServerId, localServerId);
            _clientGM.Start();
            _clientGM.ShowPrompt();

            var dataConfig = serverConfig["DatabaseServer"];
            ip = dataConfig.Value<string>("Ip");
            port = dataConfig.Value<int>("Port");
            long dbServerId = dataConfig.Value<long>("Id");
            _clientDatabase = new NetClient();
            _clientDatabase.Config(_managerDatabase, ip, port, connectionCount, bufferSize, dbServerId, localServerId);
            _clientDatabase.Start();
            _clientDatabase.ShowPrompt();

            var gatewayConfig = serverConfig["GatewayServer"];
            ip = gatewayConfig.Value<string>("InnerIp");
            var gatewayList = gatewayConfig["List"].ToArray();
            for (int i = 0; i < gatewayList.Length; i++)
            {
                var item = gatewayList[i];
                port = item.Value<int>("InnerPort");
                long gateServerId = item.Value<int>("Id");
                NetClient gateClient = new NetClient();
                gateClient.Config(_managerGateway, ip, port, connectionCount, bufferSize, gateServerId, localServerId);
                gateClient.Start();
                gateClient.ShowPrompt();
            }

            NetNodeReconnect.Instance.Init();
        }

        public void Run()
        {
            _managerLogin.DoNetMessages();
            _managerDatabase.DoNetMessages();
            _managerGateway.DoNetMessages();
            _managerGM.DoNetMessages();
        }

        public void Stop()
        {
            NetNodeReconnect.Instance.Release();

            _managerLogin.StopNetwork();
            _managerDatabase.StopNetwork();
            _managerGM.StopNetwork();
            _managerGateway.StopNetwork();
        }

        public void Release()
        {
        }
    }
}
